/*!
\file AlgBellmanFord.cpp
\brief Contains implementation of AlgBellmanFord.
*/

#include"AlgBellmanFord.h" 

#define INF 9999.0

/*!
\def INF
\brief A very big number.
*/

AlgBellmanFord::AlgBellmanFord( Graph *g ):Algorithm(g){
	containerAdd();
}

AlgBellmanFord::~AlgBellmanFord(){
	
}

void AlgBellmanFord::run(){
	Node *n = getNode("Please select the source Node");
	for( unsigned int i = 0; i < graph()->numNodes(); i++ ){
		const Node &node = graph()->node(i);
		c().push_back( (new ContainerElement)->setNode(node)->setData(node==*n?0.0:INF) );
	}
	
	for( unsigned int i = 0; i < graph()->numNodes(); i++ ){
		for( unsigned int j = 0; j < graph()->numEdges(); j++ ){
			const Edge &uv = graph()->edge(j);
			const Node &u = uv.from();
			const Node &v = uv.to();
			
			double total = distance(u)+weight(uv);
			if( total < distance(v) ){
				setData(v, total, uv );
			}
			
			if(!graph()->isDirected()){
				total = distance(v)+weight(uv);
				if( total < distance(u) )
					setData(u, total, uv);
			}
		}
	}
}

void AlgBellmanFord::setData( const Node &n, double d, const Edge &e ){
	for( unsigned int i = 0; i < c().size(); i++ ){
		if( *c()[i]->node() == n ){
			c()[i]->setData(d)->setEdge(e);
			return;
		}
	}
}

double AlgBellmanFord::distance(const Node &n){
	for( unsigned int i = 0; i < c().size(); i++ ){
		if( *c()[i]->node() == n )
			return c()[i]->dataDouble();
	}
	return INF;
}

double AlgBellmanFord::weight(const Edge &e){
	return e.label().remove("\"").toDouble();
}
